package top.jacktgq.itheima.netty.protocol_design.groupchat.client.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import top.jacktgq.itheima.netty.protocol_design.groupchat.client.ChatClient;
import top.jacktgq.itheima.netty.protocol_design.groupchat.message.*;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.concurrent.CyclicBarrier;

/**
 * @Author CandyWall
 * @Date 2022/2/26--14:59
 * @Description
 */
@Slf4j
@ChannelHandler.Sharable
/**
 * 客户端聊天消息处理
 */
public class ClientMessageHandler extends SimpleChannelInboundHandler<Message> {
    private final Scanner scanner;
    private final CyclicBarrier WAIT_FOR_LOGIN;
    private volatile boolean loginSuccess;

    public ClientMessageHandler(Scanner scanner, CyclicBarrier WAIT_FOR_LOGIN) {
        this.scanner = scanner;
        this.WAIT_FOR_LOGIN = WAIT_FOR_LOGIN;
        loginSuccess = false;
    }

    @Override
    /**
     * 在连接建立后触发Active事件
     */
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 创建新的线程，接收用户在控制台的输入
        new Thread(() -> {
            String username = null;
            while (!loginSuccess) {
                System.out.print("请输入用户名：");
                username = scanner.nextLine();
                System.out.print("请输入密码：");
                String password = scanner.nextLine();
                // 创建登录请求消息对象
                LoginRequestMessage loginRequestMessage = new LoginRequestMessage(username, password);
                // 给服务器发送登录请求
                ctx.writeAndFlush(loginRequestMessage);

                // 先阻塞住，等待验证登录的结果
                try {
                    WAIT_FOR_LOGIN.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 不管登录成功失败，都会去循环条件处进行校验
            }

            // 如果登录成功就退出上面的循环，进入聊天阶段
            while (true) {
                System.out.println("==================================");
                System.out.println("send [username] [content]");
                System.out.println("gsend [group name] [content]");
                System.out.println("gcreate [group name] [m1,m2,m3...]");
                System.out.println("gmembers [group name]");
                System.out.println("gjoin [group name]");
                System.out.println("gquit [group name]");
                System.out.println("quit");
                System.out.println("==================================");
                String command = null;
                command = scanner.nextLine();
                String[] strs = command.split(" ");
                Message message = null;
                switch (strs[0]) {
                    case "send":
                        message = new ChatRequestMessage(username, strs[1], strs[2]);
                        break;
                    case "gsend":
                        message = new GroupChatRequestMessage(username, strs[1], strs[2]);
                        break;
                    case "gcreate":
                        HashSet<String> set = new HashSet(Arrays.asList(strs[2].split(",")));
                        // 将自己也加入群聊
                        set.add(username);
                        message = new GroupCreateRequestMessage(strs[1], set);
                        break;
                    case "gmembers":
                        message = new GroupMembersRequestMessage(strs[1]);
                        break;
                    case "gjoin":
                        message = new GroupJoinRequestMessage(username, strs[1]);
                        break;
                    case "gquit":
                        message = new GroupQuitRequestMessage(username, strs[1]);
                        break;
                    case "quit":
                        ctx.channel().close();
                        //break;
                        // 注意这里不是break，break只能跳出当前的switch代码块，而不能跳出while循环，因此要使用return，直接从键盘获取输入的线程的run方法中返回，而不是停留在while循环里面。
                        return;
                }
                if (message != null) {
                    ctx.writeAndFlush(message);
                }
            }


        }, "Login_Input").start();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {
        // 获取服务器端发来的消息
        log.debug("服务器端消息：{}", msg);
        // 根据消息的类型来各自做不同的处理
        // 登录消息单独处理
        if (msg.getMessageType() == 1) {
            LoginResponseMessage responseMessage = (LoginResponseMessage) msg;
            if (responseMessage.isSuccess()) {
                loginSuccess = true;
                System.out.println(responseMessage.getReason());
            } else {
                System.out.println(responseMessage.getReason());
            }
            WAIT_FOR_LOGIN.await();
        } else {
            msg.handle(ctx);
        }
    }
}
